package com.jy.rhin.support.notification.convertor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.jy.rhin.infra.exception.RhinAggrErrorType;
import com.jy.rhin.infra.exception.RhinAggrException;
import com.jy.rhin.infra.repo.notfication.topic.query.TopicQueryHandler;
import com.jy.rhin.sdk.dto.notification.req.TopicExpDto;
import com.jy.rhin.sdk.dto.notification.resp.PublishMessageDto;
import com.jy.rhin.sdk.dto.notification.resp.TopicPropertiesDto;
import com.jy.rhin.support.util.XmlUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * @Description: 默认消息转换实现类
 * @Author: lww
 * @Date: 2022/7/28 17:06
 */
@Service("defaultConverter")
@Slf4j
public class DefaultConverter extends BaseNotificationConverter {

    /**
     * 路径前缀
     */
    private static final String PARENT_ELEMENT = "/Notify/NotificationMessage/Message/";
    private static final String RHIN = "rhin:";
    private static final String NULL = "";
    private static final String BAR = "/";
    private static final String SPOT = ".";
    private static final String JSON_PATH = "$.";

    @Resource
    TopicQueryHandler topicQueryHandler;

    @Override
    public String buildMessageContent(PublishMessageDto publishMessage) {
        String message = publishMessage.getMessage();
        String topicExp = publishMessage.getTopicExp();
        try {
            TopicExpDto topicExpDto = new TopicExpDto();
            topicExpDto.setTopicExp(topicExp);
            List<TopicPropertiesDto> propertiesDtoList = topicQueryHandler.queryTopicProperties(topicExpDto.getTopicExp());
            if (CollectionUtils.isEmpty(propertiesDtoList)) {
                log.info("未找到主题属性字段");
                throw new RhinAggrException(RhinAggrErrorType.TOPIC_PROPERTIES_IS_NULL);
            }
            propertiesDtoList.forEach(topicPropertiesDto -> {
                String xmlPath = topicPropertiesDto.getSourcePath();
                String replace = xmlPath.replace(PARENT_ELEMENT, NULL).replace(RHIN, NULL);
                String substr = replace.substring(replace.indexOf(BAR) + 1).replace(BAR, SPOT);
                String join = JSON_PATH + substr;
                topicPropertiesDto.setSourcePath(join);
            });
            JSONObject jsonObject = new JSONObject();
            for (TopicPropertiesDto topicPropertiesDto : propertiesDtoList) {
                String xmlPath = topicPropertiesDto.getSourcePath();
                String jsonPath = topicPropertiesDto.getTargetPath();
                if (StringUtils.isEmpty(jsonPath)) {
                    continue;
                }
                Object value = JSONPath.read(message, jsonPath);
                if (value instanceof String && !StringUtils.isEmpty(value)) {
                    JSONPath.set(jsonObject, xmlPath, value);
                }
                if (basicType(value) && Objects.nonNull(value)) {
                    JSONPath.set(jsonObject, xmlPath, value);
                }
            }
            String className = propertiesDtoList.get(0).getClassName();
            Class clazz = Class.forName(className);
            Object obj = JSON.parseObject(jsonObject.toJSONString(), clazz);
            return XmlUtils.objToXmlString(obj);
        } catch (ClassNotFoundException e) {
            throw new RhinAggrException(RhinAggrErrorType.MESSAGE_PARSER_ERROR);
        }
    }

    /**
     * 判断值是否属于对应类型
     *
     * @param value
     * @return
     */
    private boolean basicType(Object value) {
        return value instanceof Integer || value instanceof Long || value instanceof Boolean;
    }
}
